﻿using UnityEngine;
using System.Collections;

public class MissileManager : MonoBehaviour, IResettable {

    public float lateralForceFactor = 10.0f;
    public float minimumVelocity = 1.0f;

    public float maximumVelocity = 10.0f;

    private GyroscopeReader gyroscopeReader;

    /// <summary>
    /// Variables for debugging lateral forces. Remove when no longer needed.
    /// </summary>
    Vector3 lateralDirection = Vector3.zero;
    Vector3 adjustment = Vector3.zero;

	public GameObject endExplosion;

    private Vector3 turningForce = Vector3.zero;
    // Use this for initialization
	void Start () {

        gyroscopeReader = GameObject.FindGameObjectWithTag("gyroscope").GetComponent<GyroscopeReader>();
        ResetItemList.Instance.AddItem(this);

        FollowActionPriorityQueue.Instance.AddFollowPosition(new MissilePrioritizedFollowPosition(this));

    }
	
	// Update is called once per frame
	void Update () {
	

        Vector3 currentVelocity = this.rigidbody.velocity;
        lateralDirection = Vector3.Cross(currentVelocity, Camera.main.transform.forward);   // TODO: Make sure that camera-forward is always what we want!
        adjustment = Quaternion.AngleAxis(gyroscopeReader.rotationChangeDegrees.z, Camera.main.transform.forward) * currentVelocity;
        float magnitude = Vector3.Dot(adjustment, lateralDirection);
        turningForce = lateralDirection.normalized * magnitude * lateralForceFactor;

        this.rigidbody.AddForce(turningForce);

        if (this.rigidbody.velocity.magnitude > maximumVelocity)
        {
            // Remove force by adding force in the opposite direction
            float velocityOverage = this.rigidbody.velocity.magnitude - maximumVelocity;

            float accelerationMagnitude = velocityOverage / Time.deltaTime;

            if (float.IsInfinity(accelerationMagnitude))
            {
                print("Time.delta time is " + Time.deltaTime);
                print("Current velocity is " + this.rigidbody.velocity.magnitude);
            }

            this.rigidbody.AddForce(-this.rigidbody.velocity * accelerationMagnitude);
        }
        
        // Look where you're going
        float theta = Mathf.Atan2(this.rigidbody.velocity.y, this.rigidbody.velocity.x);

        this.transform.rotation = Quaternion.Euler(0, 0, theta * Mathf.Rad2Deg);


	}

    void OnCollisionEnter(Collision collision)
    {
		GameObject.Instantiate (endExplosion, transform.position, Quaternion.identity);
        Destroy(this.gameObject);
    }

    bool destroyed = false;
    public bool IsDestroyed { get { return destroyed; } }

    public void Reset()
    {
        if (!destroyed && this.gameObject != null)
        {
            destroyed = true;
            Destroy(this.gameObject);
        }
    }


    public bool PersistAfterReset()
    {
        return false;
    }

    void OnDestroy()
    {
        ResetItemList.Instance.RemoveItem(this);
        this.destroyed = true;
    }
}
